package com.tbit.uqbike.client.service.impl;

import com.alibaba.fastjson.JSON;
import com.tbit.common.constant.CommonConstant;
import com.tbit.uqbike.client.constant.enums.PopUpEffectType;
import com.tbit.uqbike.client.dao.core.AccountDao;
import com.tbit.uqbike.client.dao.core.NoticeDao;
import com.tbit.uqbike.client.dao.core.NoticeReadLogDao;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.pojo.vo.NoticeVO;
import com.tbit.uqbike.client.service.NoticeService;
import com.tbit.uqbike.client.service.RideLogService;
import com.tbit.uqbike.client.util.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class NoticeServiceImpl implements NoticeService {
    private static final ThreadLocal<List<Integer>> threadLocalRoleIdList = new ThreadLocal<>();
    private static final ThreadLocal<List<Integer>> threadLocalUserAccountIdList = new ThreadLocal<>();

    @Autowired
    private NoticeReadLogDao noticeReadLogDao;
    @Autowired
    private NoticeDao noticeDao;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private AccountDao accountDao;


    /**
     * @description: 获取用户公告列表
     * @author: mo.shanyong
     * @date: 2025/2/19 17:16
     * @param: pageNum 页码
     * @param: pageSize 页长
     * @param: user 登录用户
     * @return: java.util.List<com.tbit.uqbike.object.pojo.Notice>
     */
    @Override
    public List<Notice> getUserNoticeList(Integer pageNum, Integer pageSize, User user,Integer accountId) {
        //获取当前用户所有的区域Id
        List<Integer> userAllAccountIdList = new ArrayList<>(Collections.singletonList(accountId));
        //设置了全部区域的公告也要能查询到
        userAllAccountIdList.add(0);
        threadLocalUserAccountIdList.set(userAllAccountIdList);
        //判断当前用户所属的用户类型
        List<Integer> userTypeList = this.noticeCheckUserType(user.getUserId());
//        log.info("userId:{},userPhone:{},userTypeList----->{}", user.getUserId(),user.getPhone(),JSON.toJSONString(userTypeList));
        threadLocalRoleIdList.set(userTypeList);
        //标志用户已读公告的日志类型是点击PV日志
        return noticeDao.getUserNoticeList(userTypeList, user.getPhone(),
                CommonConstant.NOTICE_LOG_TYPE_READ_PV,user.getUserId(), CommonConstant.NOTICE_CLIENT_PLATFORM,userAllAccountIdList,
                Objects.nonNull(pageNum) && Objects.nonNull(pageSize) ? (pageNum - 1) * pageSize : null, pageSize);
    }
    /**
     * @description: 查询用户的公告总数
     * @author: mo.shanyong
     * @date: 2025/2/19 18:08
     * @param: user
     * @return: int
     */
    @Override
    public int getUserNoticeCount(User user) {
        //判断当前用户所属的用户类型
//        Integer userType = this.noticeCheckUserType(user);
        List<Integer> userTypeList = threadLocalRoleIdList.get();
        List<Integer> userAccountIdList = threadLocalUserAccountIdList.get();
        return noticeDao.getUserNoticeCount(userTypeList, user.getPhone(),userAccountIdList,CommonConstant.NOTICE_CLIENT_PLATFORM);
    }
    /**
     * @description:
     * @author: mo.shanyong
     * @date: 2025/2/24 21:10
     * @param: platform 平台：1、客户端；2、管理端；3、运维端
     * @param: user
     * @return: int
     */
    @Override
    public int getUserNotReadNoticeCount(User user) {
        List<Integer> roleIdList = threadLocalRoleIdList.get();
        List<Integer> userAccountIdList = threadLocalUserAccountIdList.get();
        Integer userNotReadNoticeCount = noticeDao.getUserNotReadNoticeCount(roleIdList, user.getPhone(), CommonConstant.NOTICE_LOG_TYPE_READ_PV,
                user.getUserId(), CommonConstant.NOTICE_CLIENT_PLATFORM,userAccountIdList);
        userNotReadNoticeCount = Objects.isNull(userNotReadNoticeCount) ? 0 : userNotReadNoticeCount;
        threadLocalRoleIdList.remove();
        threadLocalUserAccountIdList.remove();
        return userNotReadNoticeCount;
    }

    /**
     * @description: 记录对公告的操作日志
     * @author: mo.shanyong
     * @date: 2025/2/20 15:52
     * @param: noticeId 公告id
     * @param: operateType 操作类型：1、曝光；3、点击；5、阅读(目前只记了这个)
     * @param: user
     * @return: java.lang.Integer
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer recordNoticeLog(Integer noticeId, Integer operateType, User user) {
        //记录日志
        Date now = new Date();
        Integer logId = this.addNoticeLog(noticeId, operateType, user, now, CommonConstant.NOTICE_CLIENT_PLATFORM);
        return logId;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertCheckNull(NoticeVO noticeVO) {
        Notice notice = new Notice();
        BeanUtils.copyProperties(noticeVO,notice,"startTime","endTime");
        notice.setCreateAccountUserId(0);//系统
        notice.setStartTime(DateTimeUtil.StringToDateTime(noticeVO.getStartTime()));
        notice.setEndTime(DateTimeUtil.StringToDateTime(noticeVO.getEndTime()));
        Date now = new Date();
        notice.setCreateTime(now);
        notice.setUpdateTime(now);
        this.noticeDao.insertCheckNull(notice);
        noticeVO.setId(notice.getId());
        noticeVO.getAppointUserTypeList().forEach(noticeAppointType -> {
            noticeAppointType.setNoticeId(notice.getId());
        });
        //添加公告指令用户
        List<NoticeAppointType> appointUserTypeList = noticeVO.getAppointUserTypeList();
        noticeDao.insertBatchNoticeType(appointUserTypeList);
        //添加公告指定生效运营区域
        this.insertNoticeAppointAccount(noticeVO);
        //添加公告指定生效平台
        this.insertNoticeAppointPlatform(noticeVO.getPlatformList(), notice.getId());
    }

    /**
     * @description: 记录对公告的操作日志
     * @author: mo.shanyong
     * @date: 2025/2/20 16:11
     * @param: noticeId 公告id
     * @param: logType 操作类型：1、曝光；3、点击；5、阅读(目前只记了这个)
     * @param: user 用户
     */
    private Integer addNoticeLog(Integer noticeId, Integer logType, User user,Date now,Integer platform){
        //PV的数据量一定要记录
        NoticeReadLog noticeReadLogPV = new NoticeReadLog();
        noticeReadLogPV.setLogType(logType);
        noticeReadLogPV.setCreateTime(now);
        noticeReadLogPV.setUserId(user.getUserId());
        noticeReadLogPV.setNoticeId(noticeId);
        noticeReadLogPV.setPlatform(platform);
        noticeReadLogDao.insertCheckNull(noticeReadLogPV);
        return noticeReadLogPV.getId();
    }

    /**
     * @description: 判断用户类型（1、新用户，2、老用户，3、7日内新用户，4、30日内新用户）
     * @author: mo.shanyong
     * @date: 2025/2/21 10:38
     * @param: user
     * @return: java.lang.Integer
     */
    private List<Integer> noticeCheckUserType(Integer userId){
        List<Integer> tagList = new ArrayList<>();
        // 新用户 无完成支付的骑行订单
        Integer allRideCount = rideLogService.getRideCount(userId, -1);
        if (allRideCount == 0){
            tagList.add(Integer.parseInt(PopUpEffectType.NEW_USER.getCode()));
        }else { // 老用户
            tagList.add(Integer.parseInt(PopUpEffectType.OLD_USER.getCode()));
        }
        // 七日内订单
        Integer rideCountInSevenDays = rideLogService.getRideCount(userId, 7);
        // 7日新用户
        if (rideCountInSevenDays != 0 && (allRideCount - rideCountInSevenDays) == 0){
            tagList.add(Integer.parseInt(PopUpEffectType.SEVEN_DAY_NEW_USER.getCode()));
        }
        Integer rideCountInThirtyDays = rideLogService.getRideCount(userId, 30);
        // 30日新用户
        if (rideCountInThirtyDays!= 0 && (allRideCount - rideCountInThirtyDays) == 0){
            tagList.add(Integer.parseInt(PopUpEffectType.MONTH_NEW_USER.getCode()));
        }
        return tagList;
    }


    /**
     * @description: 插入公告指定生效运营区域
     * @author: mo.shanyong
     * @date: 2025/2/19 15:05
     * @param: noticeVO
     */
    private void insertNoticeAppointAccount(NoticeVO noticeVO){
        //找到全部的区域id
        List<Integer> accountIdList = accountDao.getAllAccountIdByIds(noticeVO.getAccountIdList());
        this.insertNoticeAccountIds(accountIdList,noticeVO.getId());
    }

    /**
     * @description: 批量插入公告生效的区域id
     * @author: mo.shanyong
     * @date: 2025/2/21 16:34
     * @param: accountIdList
     * @param: noticeId 公告Id
     */
    private void insertNoticeAccountIds(List<Integer> accountIdList,Integer noticeId){
        List<NoticeAppointAccount> noticeAppointAccountList = new ArrayList<>();
        for (Integer accountId : accountIdList) {
            NoticeAppointAccount noticeAppointAccount = new NoticeAppointAccount();
            noticeAppointAccount.setAccountId(accountId);
            noticeAppointAccount.setNoticeId(noticeId);
            noticeAppointAccountList.add(noticeAppointAccount);
        }
        noticeDao.insertBatchNoticeAccount(noticeAppointAccountList);
    }

    /**
     * @description: 添加公告指定生效平台
     * @author: mo.shanyong
     * @date: 2025/2/19 15:47
     * @param: platformList 指定生效平台id
     * @param: noticeId 公告id
     */
    private void insertNoticeAppointPlatform(List<Integer> platformList,Integer noticeId){
        List<NoticeAppointPlatform> noticeAppointPlatformList = new ArrayList<>();
        for (Integer platform : platformList) {
            NoticeAppointPlatform noticeAppointPlatform = new NoticeAppointPlatform();
            noticeAppointPlatform.setPlatform(platform);
            noticeAppointPlatform.setNoticeId(noticeId);
            noticeAppointPlatformList.add(noticeAppointPlatform);
        }
        noticeDao.insertBatchNoticePlatform(noticeAppointPlatformList);
    }
}
